<?php
namespace iBrand\Shop\Server\Http\Controllers;

use Carbon\Carbon;
use iBrand\Component\Payment\Contracts\PaymentChargeContract;
use iBrand\Server\Http\Controllers\Controller;
use iBrand\Shop\Core\Models\Balance;
use iBrand\Shop\Core\Models\BalanceCash;
use iBrand\Shop\Core\Models\BalanceOrder;
use iBrand\Shop\Core\Models\ClerkBalanceOrder;
use iBrand\Shop\Core\Repositories\BalanceRepository;
use iBrand\Shop\Core\Repositories\UserShopRepository;
use iBrand\Shop\Core\Repositories\ClerkRepositoryEloquent;
use iBrand\Component\BankAccount\Model\BankAccount;
use iBrand\Component\Payment\Services\PaymentService;
use iBrand\Component\User\Models\User;
use iBrand\Shop\Server\Transformers\BalanceCashTransformer;
use iBrand\Shop\Server\Transformers\BalanceTransformer;
use iBrand\Shop\Server\Transformers\ClerkBalanceTransformer;
use DB;
use Illuminate\Http\Request;
use Validator;
use iBrand\Component\Payment\Models\Payment;
use iBrand\Shop\Core\Repositories\BalanceOrderRepository;
use iBrand\Shop\Core\Repositories\ClerkBalanceOrderRepository;

use iBrand\Shop\Backend\Model\Shop;

class BalanceController extends Controller
{

    protected $balanceRepository;
    private $payment;
    private $userShopRepository;
    private $clerkRepository;
    protected $balanceOrderRepository;
    protected $clerkBalanceOrderRepository;
    private $charge;

    public function __construct(PaymentService $paymentService, BalanceRepository $balanceRepository
        , UserShopRepository $userShopRepository
        , ClerkRepositoryEloquent $clerkRepository
        , BalanceOrderRepository $balanceOrderRepository
        , ClerkBalanceOrderRepository $clerkBalanceOrderRepository
        , PaymentChargeContract $chargeContract

    )
    {
        $this->payment = $paymentService;
        $this->balanceRepository = $balanceRepository;
        $this->userShopRepository = $userShopRepository;
        $this->clerkRepository = $clerkRepository;
        $this->balanceOrderRepository = $balanceOrderRepository;
        $this->clerkBalanceOrderRepository = $clerkBalanceOrderRepository;
        $this->charge = $chargeContract;
    }

    public function index()
    {
        $type = request('type');
        return $this->response()->paginator($this->balanceRepository->fluctuation(request()->user()->id, $type)->paginate(),
            new BalanceTransformer());
    }

    public function getClerkOwnerMobile()
    {
        $clerk = auth('clerk')->user();
        if (!$mobile = $this->clerkRepository->getClerkOwnerMobileByShopId($clerk->shop_id)) {
            return $this->api([], false, 405, '店长手机号不存在');
        }
        return $this->api(['mobile' => $mobile], true, 200, '');
    }

    public function sum($user_id)
    {

        $clerk = auth('clerk')->user();
        /*if (!$this->userShopRepository->getUserInfoByShopId($clerk->shop_id, $user_id)) {
            return $this->api([], false, 405, '该会员非本门店会员');
        };*/
        $sum = Balance::sumByUser($user_id);
        if (!is_numeric($sum)) {
            $sum = 0;
        } else {
            $sum = (int)$sum;
        }

        return $this->api(number_format($sum / 100, 2, ".", ""));

    }


    public function BalanceRecord()
    {
        $clerk = auth('clerk')->user();
        $lists = $this->balanceOrderRepository->getBalanceOrderByShopClerk($clerk);
        return $this->response()->paginator($lists, new BalanceTransformer());
    }


    public function UserBalance($user_id)
    {
        $clerk = auth('clerk')->user();
        /*if (!$this->userShopRepository->getUserInfoByShopId($clerk->shop_id, $user_id)) {
            return $this->api([], false, 405, '该会员非本门店会员');
        }*/
        $type = request('type');
        if (!$type) {
            $res = $this->clerkBalanceOrderRepository->getClerkBalanceOrderByUserId($user_id, $clerk->shop_id);
            return $this->response()->paginator($res, new ClerkBalanceTransformer());
        }
        $list = $this->balanceRepository->getShopOrder($user_id);
        return $this->response()->paginator($list, new BalanceTransformer());
    }


    public function charge($user_id, Request $request)
    {

        $clerk = auth('clerk')->user();

        $code = request('code');

        $mobile = request('mobile');

        $title = '';


        $credentials = [
            'mobile' => $mobile,
            'verifyCode' => $code,
        ];


        /*$validator = Validator::make($credentials, [
            'mobile' => 'required|confirm_mobile_not_change|confirm_rule:mobile_required',
            'code' => 'required|verify_code',
        ]);

        if ($validator->fails()) {
            return $this->api([], false, 400, $validator->errors());
        }*/


        if (!$this->clerkRepository->getClerk0wnerByMobile($clerk->shop_id, $mobile)) {
            return $this->api([], false, 405, '输入的店长手机有误');
        }
        /*if (!$this->userShopRepository->getUserInfoByShopId($clerk->shop_id, $user_id)) {
            return $this->api([], false, 405, '该会员非本门店会员');
        };*/
        $channel = request('channel');

        $note = request('note');

        $pay_amount = request('pay_amount') ? request('pay_amount') : 0;

        $give = request('give') ? request('give') : 0;


        if (!$give && !$pay_amount) return $this->api([], false, 402, '');

        if (!$channel || !in_array($channel, ['wx_pub_qr'])) return $this->api([], false, 402, '支付方式错误');

        $time = Carbon::now();

        try {

            DB::beginTransaction();

            if ($shop = Shop::find($clerk->shop_id)) {
                $title = $shop->name . ' 会员储蓄卡 充值' . ((abs($pay_amount) + abs($give))) . '元';
            }

            $order = BalanceOrder::create(['user_id' => $user_id, 'order_no' => build_order_no('R'), 'pay_type' => $channel
                , 'amount' => (abs($pay_amount) + abs($give)) * 100, 'pay_amount' => abs($pay_amount) * 100]);

            ClerkBalanceOrder::create(['clerk_id' => $clerk->id, 'balance_order_id' => $order->id, 'shop_id' => $clerk->shop_id, 'note' => $note, 'title' => $title]);

            DB::commit();

            return $this->api($this->charge->createCharge($user_id, $channel, 'recharge', $order->order_no, $order->pay_amount,
                '余额充值', '余额充值', request()->getClientIp(), '', request('extra')));

        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception->getMessage() . $exception->getTraceAsString());
            $this->response()->errorInternal($exception->getMessage());
        }

        return $this->api([], false, 400, '支付参数错误');

    }


    public function detail($order_no)
    {

        $balance = $this->balanceOrderRepository->getBalanceOrderByOrderNo($order_no);

        if (count($balance) > 0) {
            return $this->api($balance, true, 200, '');
        }

        return $this->api([], false, 400, '');
    }


    public function paid()
    {

        $clerk = auth('clerk')->user();

        $order_no = request('order_no');

        if (!$order_no || !$order = BalanceOrder::where('order_no', $order_no)->first()) {
            return $this->response()->errorBadRequest('订单不存在');
        }

        if (settings('pingxx_pay_scene') == 'test') {
            if ($order AND $order->pay_status == 0 AND $order->pay_amount == request('pay_amount')) {
                $order->pay_status = 1;
                $order->pay_time = Carbon::now();
                $order->save();
                Balance::create(['user_id' => $order->user_id, 'type' => 'recharge', 'note' => '充值', 'value' => $order->amount, 'origin_id' => $order->id, 'origin_type' => 'iBrand\Component\Balance\Model\BalanceOrder']);
            }
        }

        if ($order->pay_status) {
            return $this->api(compact('order'));
        }

        return $this->api([], false, 400, '');

    }


    public function uploadTicket()
    {
        $order_no = request('order_no');
        $images = request('images');
        if (!$order_no || !$images) {
            return $this->api([], false, 405, '');
        }
        if (!$order_no || !$order = BalanceOrder::where('order_no', $order_no)->first()) {
            return $this->response()->errorBadRequest('订单不存在');
        }

        $clerk = auth('clerk')->user();

        if (!$shopOrder = $this->balanceOrderRepository->getBalanceOrderByOrderNoClerkID($order_no, $clerk)) {
            return $this->api([], false, 400, '无权操作此订单');
        };

        if ($this->clerkBalanceOrderRepository->update(['images' => json_encode($images)], $shopOrder->clerkBalance->id)) {
            return $this->api([], true, 200, '上传小票成功');
        };

        return $this->api([], false, 405, '上传小票失败');

    }


    public function amountConfirmArrival()
    {

        $order_no = request('order_no');

        $clerk = auth('clerk')->user();

        $channel = request('channel');
        if (!$channel || !in_array($channel, ['pop_cash_pay', 'cash_pay', 'ali_scan_pay'])) {
            return $this->api([], false, 402, '支付方式错误');
        }

        if (!$order_no || !$order = BalanceOrder::where('order_no', $order_no)->first()) {
            return $this->response()->errorBadRequest('订单不存在');
        }

        if (!$shopOrder = $this->balanceOrderRepository->getBalanceOrderByOrderNoClerkID($order_no, $clerk)) {
            return $this->api([], false, 400, '无权操作此订单');
        };

        $time = Carbon::now();

        try {

            DB::beginTransaction();

            if ($order AND $order->pay_status == 0) {
                $order->pay_status = 1;
                $order->pay_type = $channel;
                $order->pay_time = date('Y-m-d H:i:s', $time->timestamp);
                $order->save();
                Balance::create(['user_id' => $order->user_id, 'type' => 'recharge', 'note' => '充值', 'value' => $order->amount, 'origin_id' => $order->id, 'origin_type' => 'iBrand\Component\Balance\Model\BalanceOrder']);
            }

            DB::commit();

            return $this->api($order);

        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception->getMessage() . $exception->getTraceAsString());
            $this->response()->errorInternal($exception->getMessage());
        }

    }

    /**
     * 操作余额页面
     */
    public function opBalanceBase()
    {
        $clerk = auth('clerk')->user();

        if (!$user_id = request('user_id')) {
            return $this->api([], false, 400, '用户不存在');
        }

        if (!$clerk->shops->is_clerk_owner) {
            return $this->api([], false, 400, '无权限操作');
        }

        /*if (!$user = $this->userShopRepository->getUserInfoByShopId($clerk->shop_id, $user_id)) {
            return $this->api([], false, 400, '该会员非本门店会员');
        }*/
        $user = User::with('card')->with('shop')->find($user_id);

        $sum = Balance::sumByUser($user_id);
        if (!is_numeric($sum)) {
            $sum = 0;
        } else {
            $sum = (int)$sum;
        }
        $balance = number_format($sum / 100, 2, ".", "");

        $option = config('o2o.shop_owner_op_rule.balance');
        $type = [];
        $i = 0;
        foreach ($option as $key => $item) {
            $type[$i]['name'] = $key;
            $type[$i]['value'] = $item;
            $i++;
        }

        return $this->api(['user' => $user, 'balance' => $balance, 'option' => $type]);
    }

    /**
     * 操作余额
     * @return \Dingo\Api\Http\Response
     */
    public function handleBalance()
    {
        $clerk = auth('clerk')->user();
        if (!$user_id = request('user_id')) {
            return $this->api([], false, 400, '用户不存在');
        }

        if (!$clerk->shops->is_clerk_owner) {
            return $this->api([], false, 400, '无权限操作');
        }

        /*if (!$user = $this->userShopRepository->getUserInfoByShopId($clerk->shop_id, $user_id)) {
            return $this->api([], false, 400, '该会员非本门店会员');
        }*/
        if (!$type = request('type') OR !$amount = request('amount') * 100 OR !$user_id = request('user_id')) {
            return $this->api([], false, 400, '请完善操作信息');
        }

        $note = config('o2o.shop_owner_op_rule.balance_note')[$type] . request('note');

        if ($type == 'clerk_balance_consumption' OR $type == 'clerk_balance_other') {
            $amount = -$amount;
        }

        $balance = Balance::create([
            'user_id' => $user_id,
            'type' => $type,
            'note' => $note,
            'value' => $amount,
            'origin_id' => $clerk->id,
            'origin_type' => 'iBrand\Shop\Core\Models\Clerk']);
        $data = ['user_id' => $user_id, 'value' => $amount / 100];
        event('member.balance.changed', [$data]);
        return $this->api(['balance' => $balance]);

    }


}